package com.kurt.controller;

import com.kurt.annotation.Log;
import com.kurt.common.PageResult;
import com.kurt.common.Result;
import com.kurt.dto.MenuDTO;
import com.kurt.dto.RoleDTO;
import com.kurt.dto.create.RoleCreateRequest;
import com.kurt.dto.query.RoleQueryRequest;
import com.kurt.dto.update.RoleUpdateRequest;
import com.kurt.service.RoleService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 角色管理控制器
 * 提供角色相关的REST API接口
 */
@Slf4j
@RestController
@RequestMapping("/roles")
@RequiredArgsConstructor
public class RoleController extends BaseController {

    private final RoleService roleService;

    /**
     * 创建角色
     *
     * @param createRequest 创建请求
     * @return 创建结果
     */
    @Log(title = "创建角色", businessType = 1)
    @PostMapping
    public Result<RoleDTO> createRole(@Valid @RequestBody RoleCreateRequest createRequest) {
        try {
            log.info("创建角色请求: {}", createRequest.getName());
            RoleDTO role = roleService.createRole(createRequest);
            return Result.success("角色创建成功", role);
        } catch (Exception e) {
            log.error("创建角色失败", e);
            return Result.error("创建角色失败: " + e.getMessage());
        }
    }

    /**
     * 更新角色
     *
     * @param updateRequest 更新请求
     * @return 更新结果
     */
    @Log(title = "更新角色", businessType = 2)
    @PutMapping
    public Result<RoleDTO> updateRole(@Valid @RequestBody RoleUpdateRequest updateRequest) {
        try {
            log.info("更新角色请求: {}", updateRequest.getId());
            RoleDTO role = roleService.updateRole(updateRequest);
            return Result.success("角色更新成功", role);
        } catch (Exception e) {
            log.error("更新角色失败", e);
            return Result.error("更新角色失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取角色详情
     *
     * @param id 角色ID
     * @return 角色详情
     */
    @GetMapping("/{id}")
    public Result<RoleDTO> getRoleById(@PathVariable("id") Long id) {
        try {
            log.info("获取角色详情请求: {}", id);
            RoleDTO role = roleService.getRoleById(id);
            return Result.success("获取角色详情成功", role);
        } catch (Exception e) {
            log.error("获取角色详情失败", e);
            return Result.error("获取角色详情失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询角色
     *
     * @param queryRequest 查询请求
     * @return 分页结果
     */
    @PostMapping("/page")
    public Result<PageResult<RoleDTO>> getRolePage(@RequestBody RoleQueryRequest queryRequest) {
        try {
            log.info("分页查询角色请求: {}", queryRequest);
            Page<RoleDTO> page = roleService.getRolePage(queryRequest);
            PageResult<RoleDTO> pageResult = PageResult.of(
                    page.getNumber() + 1,
                    page.getSize(),
                    page.getTotalElements(),
                    page.getContent()
            );
            return Result.success("分页查询角色成功", pageResult);
        } catch (Exception e) {
            log.error("分页查询角色失败", e);
            return Result.error("分页查询角色失败: " + e.getMessage());
        }
    }

    /**
     * 查询角色列表
     *
     * @param queryRequest 查询请求
     * @return 角色列表
     */
    @PostMapping("/list")
    public Result<List<RoleDTO>> getRoleList(@RequestBody RoleQueryRequest queryRequest) {
        try {
            log.info("查询角色列表请求: {}", queryRequest);
            List<RoleDTO> roles = roleService.getRoleList(queryRequest);
            return Result.success("查询角色列表成功", roles);
        } catch (Exception e) {
            log.error("查询角色列表失败", e);
            return Result.error("查询角色列表失败: " + e.getMessage());
        }
    }

    /**
     * 删除角色
     *
     * @param id 角色ID
     * @return 删除结果
     */
    @Log(title = "删除角色", businessType = 3)
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteRole(@PathVariable("id") Long id) {
        try {
            log.info("删除角色请求: {}", id);
            boolean success = roleService.deleteRole(id);
            return Result.success("角色删除成功", success);
        } catch (Exception e) {
            log.error("删除角色失败", e);
            return Result.error("删除角色失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除角色
     *
     * @param ids 角色ID列表
     * @return 删除结果
     */
    @Log(title = "批量删除角色", businessType = 3)
    @DeleteMapping("/batch")
    public Result<Boolean> deleteRoles(@RequestBody List<Long> ids) {
        try {
            log.info("批量删除角色请求: {}", ids);
            boolean success = roleService.deleteRoles(ids);
            return Result.success("批量删除角色成功", success);
        } catch (Exception e) {
            log.error("批量删除角色失败", e);
            return Result.error("批量删除角色失败: " + e.getMessage());
        }
    }

    /**
     * 分配菜单权限
     *
     * @param roleId  角色ID
     * @param menuIds 菜单ID列表
     * @return 分配结果
     */
    @PostMapping("/{roleId}/menus")
    public Result<Boolean> assignMenus(@PathVariable("roleId") Long roleId, @RequestBody List<Long> menuIds) {
        try {
            log.info("分配角色菜单权限请求: roleId={}, menuIds={}", roleId, menuIds);
            boolean success = roleService.assignMenus(roleId, menuIds);
            return Result.success("菜单权限分配成功", success);
        } catch (Exception e) {
            log.error("分配角色菜单权限失败", e);
            return Result.error("分配角色菜单权限失败: " + e.getMessage());
        }
    }

    /**
     * 获取角色菜单权限
     *
     * @param roleId 角色ID
     * @return 菜单列表
     */
    @GetMapping("/{roleId}/menus")
    public Result<List<MenuDTO>> getRoleMenus(@PathVariable("roleId") Long roleId) {
        try {
            log.info("获取角色菜单权限请求: {}", roleId);
            List<MenuDTO> menus = roleService.getRoleMenus(roleId);
            return Result.success("获取角色菜单权限成功", menus);
        } catch (Exception e) {
            log.error("获取角色菜单权限失败", e);
            return Result.error("获取角色菜单权限失败: " + e.getMessage());
        }
    }

    /**
     * 检查角色名称是否存在
     *
     * @param name 角色名称
     * @return 是否存在
     */
    @GetMapping("/exists/name/{name}")
    public Result<Boolean> existsByName(@PathVariable("name") String name) {
        try {
            log.info("检查角色名称是否存在请求: {}", name);
            boolean exists = roleService.existsByName(name);
            return Result.success("检查角色名称是否存在成功", exists);
        } catch (Exception e) {
            log.error("检查角色名称是否存在失败", e);
            return Result.error("检查角色名称是否存在失败: " + e.getMessage());
        }
    }

    /**
     * 检查角色编码是否存在
     *
     * @param code 角色编码
     * @return 是否存在
     */
    @GetMapping("/exists/code/{code}")
    public Result<Boolean> existsByCode(@PathVariable("code") String code) {
        try {
            log.info("检查角色编码是否存在请求: {}", code);
            boolean exists = roleService.existsByCode(code);
            return Result.success("检查角色编码是否存在成功", exists);
        } catch (Exception e) {
            log.error("检查角色编码是否存在失败", e);
            return Result.error("检查角色编码是否存在失败: " + e.getMessage());
        }
    }

    /**
     * 更新角色状态
     *
     * @param id     角色ID
     * @param status 状态
     * @return 更新结果
     */
    @Log(title = "更新角色状态", businessType = 2)
    @PostMapping("/{id}/status")
    public Result<Boolean> updateStatus(@PathVariable("id") Long id, @RequestParam Integer status) {
        try {
            log.info("更新角色状态请求: id={}, status={}", id, status);
            boolean success = roleService.updateStatus(id, status);
            return Result.success("角色状态更新成功", success);
        } catch (Exception e) {
            log.error("更新角色状态失败", e);
            return Result.error("更新角色状态失败: " + e.getMessage());
        }
    }

    /**
     * 更新角色排序
     *
     * @param id        角色ID
     * @param sortOrder 排序号
     * @return 更新结果
     */
    @Log(title = "更新角色排序", businessType = 2)
    @PostMapping("/{id}/sort")
    public Result<Boolean> updateSortOrder(@PathVariable("id") Long id, @RequestParam Integer sortOrder) {
        try {
            log.info("更新角色排序请求: id={}, sortOrder={}", id, sortOrder);
            boolean success = roleService.updateSortOrder(id, sortOrder);
            return Result.success("角色排序更新成功", success);
        } catch (Exception e) {
            log.error("更新角色排序失败", e);
            return Result.error("更新角色排序失败: " + e.getMessage());
        }
    }
}
